/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_orm.htm
 *
 * Zhiqim ORM is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.orm.dbo;

import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.kernel.util.Arrays;
import org.zhiqim.orm.ORMException;
import org.zhiqim.orm.dbo.condition._Compare;
import org.zhiqim.orm.dbo.condition._Expression;
import org.zhiqim.orm.dbo.condition._In;

/**
 * 查询条件抽象类
 * @see _Compare
 * @see _Expression
 * @see _In
 * 等
 *
 * @version v1.0.0 @author zouzhigang 2017-8-23 新建与整理
 */
public abstract class Condition implements SignConstants
{
    //比较条件
    public static final String EQUAL                           = "=";           //=            等于
    public static final String EQUAL_NOT                       = "<>";          //<>           不等
    public static final String LIKE                            = "like";        //like         两边都LIKE %value%,左边%value,右边value%
    public static final String LIKE_NOT                        = "not like";    //not like         两边都LIKE %value%,左边%value,右边value%
    public static final String THEN_G                          = ">";           //>            大于
    public static final String THEN_GE                         = ">=";          //>=           大于等于
    public static final String THEN_L                          = "<";           //<            小于
    public static final String THEN_LE                         = "<=";          //<=           小于等于
    //判断条件
    public static final String IS_NULL                         = "is null";     //is null      为空
    public static final String IS_NOT_NULL                     = "is not null"; //is not null  不为空
    public static final String IN                              = "in";          //in           包含
    public static final String IN_NOT                          = "not in";      //not in       不包含
    //多重条件
    public static final String OR                              = "or";          //or           或者
    
    /*******************************************************************/
    //子类必须实现的方法
    /*******************************************************************/
    
    /**
     * 判断对象是否匹配
     * 
     * @param obj               比较的对象
     * @return                  =true表示匹配成功
     */
    public abstract boolean match(Object obj);
    
    /**
     * 生成FDbo对应的条件SQL
     * 
     * @param dbo               _Dbo/_Table/_View三种的一种
     * @param paramMap          由Selector/Updater指定的参数表
     * @return                  SQL
     * @throws ORMException     异常
     */
    public abstract String toSql(Dbo dbo, MapSO paramMap) throws ORMException;
    
    
    /*******************************************************************/
    //内部断言方法和值转换方法
    /*******************************************************************/
    
    /**
     * 验证字段在DBO中的有效性
     * 
     * @param dbo               数据库对象
     * @param field             字段
     * @throws ORMException     异常
     */
    protected void assertField(Dbo dbo, String field) throws ORMException
    {
        if (!dbo.hasField(field))
            throw new ORMException("ZTable/ZView["+dbo.getName()+"]配置中未找到["+field+"]属性");
    }
    
    /**
     * 断言是否是int[],long[],String[]三种
     * 
     * @param value             值
     * @throws ORMException     异常
     */
    protected void assertArray(Object value) throws ORMException
    {
        if (!(value instanceof int[]) && !(value instanceof long[]) && !(value instanceof String[]))
            throw new ORMException("ZTable/ZView[in/not in]仅支持int[],long[],String[]三种数组类型");
    }
    
    /**
     * 值转换，针对对象转换成数据库支持的类型
     * 
     * @param value     原值
     * @return          转换后的值
     */
    protected Object convertValue(Object value)
    {
        if (value instanceof Boolean)
        {//boolean型转换成int型
            boolean b = (Boolean)value;
            return b?1:0;
        }

        return value;
    }
    
    /**
     * 值转换，针对in/not in把对象转换成数组格式
     * 
     * @param value     原值
     * @return          转换后的值
     */
    protected String convertArray(Object value)
    {
        if (value instanceof int[])
            return "("+Arrays.toString((int[])value, ",") + ")";
        else if (value instanceof long[])
            return "("+Arrays.toString((long[])value, ",") + ")";
        else
            return "("+Arrays.toStringSql((String[])value, ",") + ")";
    }
}
